#include "user_test_draw.h"
#include "u8g2.h"
#include <stdint.h>
#include <stdbool.h>
#include "stdlib.h"
#ifndef SIGNAL_DISPLAY_H
#define SIGNAL_DISPLAY_H


// 配置参数
#define SCREEN_WIDTH        128
#define SCREEN_HEIGHT       64
#define WAVE_AREA_WIDTH     120    // 波形绘制区域宽度
#define WAVE_AREA_HEIGHT    50     // 波形绘制区域高度
#define WAVE_AREA_X         4      // 波形区域起始X坐标
#define WAVE_AREA_Y         8      // 波形区域起始Y坐标
#define MAX_SAMPLE_POINTS   240    // 最大采样点数


// 函数声明
void wave_display_init(wave_display_t *display, u8g2_t *u8g2, signal_data_t *signal);
void wave_display_set_config(wave_display_t *display, display_config_t *config);
void wave_display_auto_scale(wave_display_t *display);
void wave_display_calculate_scale(wave_display_t *display);
void wave_display_draw_grid(wave_display_t *display);
void wave_display_draw_waveform(wave_display_t *display);
void wave_display_draw_info(wave_display_t *display);
void wave_display_update(wave_display_t *display);

#endif // SIGNAL_DISPLAY_H

//==================== 实现部分 ====================

/**
 * @brief 初始化波形显示器
 * @param display 波形显示器指针
 * @param u8g2 u8g2显示器句柄
 * @param signal 信号数据指针
 */
void wave_display_init(wave_display_t *display, u8g2_t *u8g2, signal_data_t *signal)
{
    display->u8g2 = u8g2;
    display->signal = signal;
    display->center_y = WAVE_AREA_Y + WAVE_AREA_HEIGHT / 2;
    
    // 默认配置
    display->config.voltage_scale = 1.0f;    // 1V/div
    display->config.time_scale = 0.001f;     // 1ms/div
    display->config.wave_thickness = 1;
    display->config.auto_scale = true;
    
    // 初始计算缩放参数
    wave_display_calculate_scale(display);
}

/**
 * @brief 设置显示配置
 * @param display 波形显示器指针
 * @param config 配置参数指针
 */
void wave_display_set_config(wave_display_t *display, display_config_t *config)
{
    display->config = *config;
    wave_display_calculate_scale(display);
}

/**
 * @brief 自动计算合适的缩放参数
 * @param display 波形显示器指针
 */
void wave_display_auto_scale(wave_display_t *display)
{
    if (!display->config.auto_scale || !display->signal->sample_data) {
        return;
    }
    
    signal_data_t *sig = display->signal;
    
    // 计算合适的电压刻度
    float max_voltage = sig->peak_to_peak / 2.0f;
    
    // 选择合适的电压刻度值
    float voltage_scales[] = {0.01f, 0.02f, 0.05f, 0.1f, 0.2f, 0.5f, 1.0f, 2.0f, 5.0f, 10.0f};
    int scale_count = sizeof(voltage_scales) / sizeof(voltage_scales[0]);
    
    for (int i = 0; i < scale_count; i++) {
        if (max_voltage <= voltage_scales[i] * (WAVE_AREA_HEIGHT / 8.0f)) {
            display->config.voltage_scale = voltage_scales[i];
            break;
        }
    }
    
    // 计算合适的时间刻度
    if (sig->frequency > 0) {
        float period = 1.0f / sig->frequency;
        float display_time = period * 2.0f; // 显示2个周期
        
        float time_scales[] = {0.00001f, 0.00002f, 0.00005f, 0.0001f, 0.0002f, 0.0005f, 
                              0.001f, 0.002f, 0.005f, 0.01f, 0.02f, 0.05f, 0.1f, 0.2f, 0.5f};
        int time_scale_count = sizeof(time_scales) / sizeof(time_scales[0]);
        
        for (int i = 0; i < time_scale_count; i++) {
            if (display_time <= time_scales[i] * (WAVE_AREA_WIDTH / 10.0f)) {
                display->config.time_scale = time_scales[i];
                break;
            }
        }
    }
}

/**
 * @brief 计算缩放系数和显示参数
 * @param display 波形显示器指针
 */
void wave_display_calculate_scale(wave_display_t *display)
{
    signal_data_t *sig = display->signal;
    
    if (!sig->sample_data || sig->sample_count == 0) {
        return;
    }
    
    // 如果启用自动缩放，先计算合适的刻度
    if (display->config.auto_scale) {
        wave_display_auto_scale(display);
    }
    
    // 计算Y轴缩放系数 (像素/V)
    display->y_scale = (WAVE_AREA_HEIGHT / 2.0f) / (display->config.voltage_scale * 4.0f);
    
    // 计算时间轴相关参数
    float total_time = (float)sig->sample_count / sig->sample_rate;
    float display_time = display->config.time_scale * (WAVE_AREA_WIDTH / 10.0f);
    
    // 计算实际显示的采样点数
    if (total_time <= display_time) {
        display->display_points = sig->sample_count;
        display->x_scale = (float)WAVE_AREA_WIDTH / (float)sig->sample_count;
    } else {
        display->display_points = (uint16_t)(display_time * sig->sample_rate);
        if (display->display_points > sig->sample_count) {
            display->display_points = sig->sample_count;
        }
        display->x_scale = (float)WAVE_AREA_WIDTH / (float)display->display_points;
    }
}

/**
 * @brief 绘制网格线
 * @param display 波形显示器指针
 */
void wave_display_draw_grid(wave_display_t *display)
{
    u8g2_t *u8g2 = display->u8g2;
    
    // 绘制边框
    u8g2_DrawFrame(u8g2, WAVE_AREA_X - 1, WAVE_AREA_Y - 1, 
                   WAVE_AREA_WIDTH + 2, WAVE_AREA_HEIGHT + 2);
    
    // 绘制中心水平线
    u8g2_DrawLine(u8g2, WAVE_AREA_X, display->center_y, 
                  WAVE_AREA_X + WAVE_AREA_WIDTH - 1, display->center_y);
    
    // 绘制垂直网格线
    for (int i = 1; i < 10; i++) {
        int x = WAVE_AREA_X + (WAVE_AREA_WIDTH * i) / 10;
        // 虚线效果：每隔几个像素绘制一次
        for (int y = WAVE_AREA_Y; y < WAVE_AREA_Y + WAVE_AREA_HEIGHT; y += 3) {
            u8g2_DrawPixel(u8g2, x, y);
        }
    }
    
    // 绘制水平网格线
    for (int i = 1; i < 5; i++) {
        int y = WAVE_AREA_Y + (WAVE_AREA_HEIGHT * i) / 5;
        if (y != display->center_y) { // 避免重复绘制中心线
            for (int x = WAVE_AREA_X; x < WAVE_AREA_X + WAVE_AREA_WIDTH; x += 3) {
                u8g2_DrawPixel(u8g2, x, y);
            }
        }
    }
}

/**
 * @brief 将采样值转换为屏幕Y坐标
 * @param display 波形显示器指针
 * @param sample_value ADC采样值(0-4095)
 * @return 屏幕Y坐标
 */
static int16_t sample_to_screen_y(wave_display_t *display, int16_t sample_value)
{
    // 将ADC值(0-4095)转换为电压值(-1.65V ~ +1.65V)，以1.65V为中心
    float voltage = ((float)sample_value / 4095.0f) * 3.3f - 1.65f;
    
    // 转换为屏幕坐标，向下为正
    int16_t screen_y = display->center_y - (int16_t)(voltage * display->y_scale);
    
    // 限制在显示区域内
    if (screen_y < WAVE_AREA_Y) 
        screen_y = WAVE_AREA_Y;
    if (screen_y >= WAVE_AREA_Y + WAVE_AREA_HEIGHT) 
        screen_y = WAVE_AREA_Y + WAVE_AREA_HEIGHT - 1;
    
    return screen_y;
}

/**
 * @brief 绘制波形
 * @param display 波形显示器指针
 */
void wave_display_draw_waveform(wave_display_t *display)
{
    u8g2_t *u8g2 = display->u8g2;
    signal_data_t *sig = display->signal;
    
    if (!sig->sample_data || sig->sample_count == 0 || display->display_points == 0) {
        return;
    }
    
    // 设置绘图区域剪裁
    u8g2_SetClipWindow(u8g2, WAVE_AREA_X, WAVE_AREA_Y, 
                       WAVE_AREA_X + WAVE_AREA_WIDTH - 1, 
                       WAVE_AREA_Y + WAVE_AREA_HEIGHT - 1);
    
    // 计算采样点间隔，如果显示点数少于采样点数，需要跳过一些点
    display->display_points = 120;
    if((1/sig->frequency)*6 <= 0.04096)
    {
            sig->sample_count = (uint16_t)(((1/sig->frequency)*6/0.04096)*1024);
    }
    else
    sig->sample_count = 1024;
    float sample_step = (float)sig->sample_count / (float)display->display_points;
    
    int16_t prev_x = -1, prev_y = -1;
    
    // 逐点绘制波形
    for (uint16_t i = 0; i < display->display_points; i++) {
        // 计算对应的采样点索引
        uint16_t sample_index = (uint16_t)(i * sample_step);
        if (sample_index >= sig->sample_count) {
            sample_index = sig->sample_count - 1;
        }
        
        // 计算屏幕坐标
        int16_t screen_x = WAVE_AREA_X + (i * WAVE_AREA_WIDTH) / display->display_points;
        int16_t screen_y = sample_to_screen_y(display, sig->sample_data[sample_index]);
        
        // 绘制波形
        if (display->config.wave_thickness <= 1) {
            // 细线绘制
            if (i == 0) {
                // 第一个点，只绘制点
                u8g2_DrawPixel(u8g2, screen_x, screen_y);
            } else {
                // 连接到前一个点
                u8g2_DrawLine(u8g2, prev_x, prev_y, screen_x, screen_y);
            }
        } else {
            // 粗线绘制
            if (i == 0) {
                // 第一个点，绘制粗点
                for (int dy = -(display->config.wave_thickness-1)/2; 
                     dy <= display->config.wave_thickness/2; dy++) {
                    int16_t draw_y = screen_y + dy;
                    if (draw_y >= WAVE_AREA_Y && draw_y < WAVE_AREA_Y + WAVE_AREA_HEIGHT) {
                        u8g2_DrawPixel(u8g2, screen_x, draw_y);
                    }
                }
            } else {
                // 绘制粗线连接
                for (int dy = -(display->config.wave_thickness-1)/2; 
                     dy <= display->config.wave_thickness/2; dy++) {
                    int16_t draw_y1 = prev_y + dy;
                    int16_t draw_y2 = screen_y + dy;
                    if (draw_y1 >= WAVE_AREA_Y && draw_y1 < WAVE_AREA_Y + WAVE_AREA_HEIGHT &&
                        draw_y2 >= WAVE_AREA_Y && draw_y2 < WAVE_AREA_Y + WAVE_AREA_HEIGHT) {
                        u8g2_DrawLine(u8g2, prev_x, draw_y1, screen_x, draw_y2);
                    }
                }
            }
        }
        
        // 保存当前点作为下一次的前一个点
        prev_x = screen_x;
        prev_y = screen_y;
    }
    
    // 取消剪裁
    u8g2_SetMaxClipWindow(u8g2);
}

/**
 * @brief 绘制信号信息
 * @param display 波形显示器指针
 */
void wave_display_draw_info(wave_display_t *display)
{
    u8g2_t *u8g2 = display->u8g2;
    signal_data_t *sig = display->signal;
    char info_str[32];
    
    u8g2_SetFont(u8g2, u8g2_font_5x7_tr);
    
    // 显示频率信息
    if (sig->frequency < 1000) {
        snprintf(info_str, sizeof(info_str), "%.3fHz", sig->frequency);
    } else {
        snprintf(info_str, sizeof(info_str), "%.3fkHz", sig->frequency / 1000.0f);
    }
    u8g2_DrawStr(u8g2, 0, 6, info_str);
    
    // 显示幅度信息
    snprintf(info_str, sizeof(info_str), "%.3fVpp", sig->peak_to_peak);
    u8g2_DrawStr(u8g2, 65, 6, info_str);
    
    // 显示时间刻度
    /*if (display->config.time_scale < 0.001f) {
        snprintf(info_str, sizeof(info_str), "%.0fus/div", display->config.time_scale * 1000000);
    } else if (display->config.time_scale < 1.0f) {
        snprintf(info_str, sizeof(info_str), "%.1fms/div", display->config.time_scale * 1000);
    } else {
        snprintf(info_str, sizeof(info_str), "%.2fs/div", display->config.time_scale);
    }
    u8g2_DrawStr(u8g2, 0, 63, info_str);*/
    
    // 显示电压刻度
  /* if (display->config.voltage_scale < 1.0f) {
        snprintf(info_str, sizeof(info_str), "%.0fmV/div", display->config.voltage_scale * 1000);
    } else {
        snprintf(info_str, sizeof(info_str), "%.1fV/div", display->config.voltage_scale);
    }
    u8g2_DrawStr(u8g2, 65, 63, info_str);*/
}

/**
 * @brief 更新整个显示
 * @param display 波形显示器指针
 */
void wave_display_update(wave_display_t *display)
{
    u8g2_t *u8g2 = display->u8g2;
    
    // 清屏
    u8g2_ClearBuffer(u8g2);
    
    // 重新计算缩放参数
    wave_display_calculate_scale(display);
    
    // 绘制各个部分
    wave_display_draw_grid(display);
    wave_display_draw_waveform(display);
    wave_display_draw_info(display);
    
    // 发送到显示器
    u8g2_SendBuffer(u8g2);
}

//==================== 使用示例 ====================

/*
// 全局变量定义
u8g2_t u8g2;
signal_data_t current_signal;
wave_display_t wave_display;
int16_t sample_buffer[MAX_SAMPLE_POINTS];

// 在主函数中初始化
void setup_signal_display(void)
{
    // 初始化u8g2 (根据你的硬件配置)
    u8g2_Setup_ssd1306_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8x8_byte_sw_i2c, u8x8_gpio_and_delay);
    u8g2_InitDisplay(&u8g2);
    u8g2_SetPowerSave(&u8g2, 0);
    
    // 初始化信号数据结构
    current_signal.sample_data = sample_buffer;
    current_signal.sample_rate = 20000.0f; // 20kHz采样率
    
    // 初始化波形显示器
    wave_display_init(&wave_display, &u8g2, &current_signal);
}

// 在主循环中更新显示
void main_loop(void)
{
    // 更新信号测量数据
    current_signal.frequency = measured_frequency;
    current_signal.peak_to_peak = measured_peak_to_peak;
    current_signal.main_freq = measured_main_freq;
    current_signal.main_amplitude = measured_main_amplitude;
    current_signal.sample_count = actual_sample_count;
    
    // 更新显示
    wave_display_update(&wave_display);
    
    // 延时
    HAL_Delay(100);
}
*/




/**
 * @brief 绘制频谱图
 * @param u8g2 U8G2显示器对象指针
 * @param signal 信号数据指针
 * @param fft_data FFT频谱数据指针（可选，为NULL时显示理论谐波）
 * @param fft_size FFT数据点数
 * @param sample_rate 采样率
 */
void signal_display_spectrum_test(u8g2_t *u8g2, wave_t *signal, float *fft_data, uint16_t fft_size, float sample_rate,float peak)
{
    // 清屏并开始绘制
    u8g2_ClearBuffer(u8g2);
    
    // 绘制频谱图边框和标题
    u8g2_SetFont(u8g2, u8g2_font_6x10_tf);
    
    // 定义频谱显示区域
    uint8_t spec_x = 8;
    uint8_t spec_y = 16;
    uint8_t spec_width = 112;
    uint8_t spec_height = 40;
    
    // 绘制频谱图边框
    u8g2_DrawFrame(u8g2, spec_x, spec_y, spec_width, spec_height);
    
    // 如果没有FFT数据或参数无效，显示提示信息
    if (!fft_data || fft_size == 0 || sample_rate <= 0) {
        u8g2_SetFont(u8g2, u8g2_font_5x7_tf);
        u8g2_DrawStr(u8g2, spec_x + 20, spec_y + 20, "No FFT Data");
        u8g2_DrawStr(u8g2, 0, 63, "---");
        u8g2_SendBuffer(u8g2);
        return;
    }
    
    // 计算频率范围和分辨率
    float freq_resolution = sample_rate / fft_size;  // 频率分辨率 Hz/bin
    float max_display_freq = sample_rate / 2.0f;     // 奈奎斯特频率
    
    // 限制显示频率范围（可根据需要调整）
    if (max_display_freq > 10000) {
        max_display_freq = 10000;  // 限制在10kHz以内
    }
    
    // 计算显示参数
    float freq_per_pixel = max_display_freq / spec_width;
    uint16_t max_bin = (uint16_t)(max_display_freq / freq_resolution);
    if (max_bin > fft_size / 2) {
        max_bin = fft_size / 2;
    }
    
    // 找到FFT数据中的最大幅度用于归一化
    float fft_max_amp = 0.0f;
    uint16_t peak_bin = 0;
    for (uint16_t i = 1; i < max_bin; i++) {  // 跳过DC分量(i=0)
        if (fft_data[i] > fft_max_amp) {
            fft_max_amp = fft_data[i];
            peak_bin = i;
        }
    }
    
    // 如果所有FFT数据都为0，显示提示
    if (fft_max_amp <= 0) {
        u8g2_SetFont(u8g2, u8g2_font_5x7_tf);
        u8g2_DrawStr(u8g2, spec_x + 15, spec_y + 20, "No Signal");
        u8g2_DrawStr(u8g2, 0, 63, "0Hz");
        u8g2_SendBuffer(u8g2);
        return;
    }
    
    // 计算主频率（峰值频率）
    float peak_frequency = peak_bin * freq_resolution;
    
    // 绘制FFT频谱
    for (uint16_t i = 1; i < max_bin; i++) {  // 跳过DC分量
        float freq = i * freq_resolution;
        if (freq > max_display_freq) break;
        
        // 计算X坐标
        uint8_t x_pos = spec_x + (uint8_t)(freq / freq_per_pixel);
        if (x_pos >= spec_x + spec_width) break;
        
        // 归一化FFT幅度到显示高度
        float normalized_amp = fft_data[i] / fft_max_amp;
        uint8_t line_height = (uint8_t)(normalized_amp * spec_height);
        
        // 确保小信号也能显示
        if (line_height < 1 && normalized_amp > 0.02f) {  // 2%以上的信号至少显示1像素
            line_height = 1;
        }
        
        // 绘制频谱线
        if (line_height > 0) {
            // 如果是峰值频率，用粗线高亮显示
            if (i == peak_bin && line_height >= 2) {
                u8g2_DrawVLine(u8g2, x_pos, spec_y + spec_height - line_height, line_height);
                if (x_pos + 1 < spec_x + spec_width) {
                    u8g2_DrawVLine(u8g2, x_pos + 1, spec_y + spec_height - line_height, line_height);
                }
            } else {
                u8g2_DrawVLine(u8g2, x_pos, spec_y + spec_height - line_height, line_height);
            }
        }
    }
    
    // 在峰值频率位置添加标记
    uint8_t peak_x = spec_x + (uint8_t)(peak_frequency / freq_per_pixel);
    if (peak_x < spec_x + spec_width) {
        // 在峰值频率上方画三角形标记
        u8g2_DrawPixel(u8g2, peak_x, spec_y - 3);
        u8g2_DrawPixel(u8g2, peak_x - 1, spec_y - 2);
        u8g2_DrawPixel(u8g2, peak_x + 1, spec_y - 2);
        u8g2_DrawPixel(u8g2, peak_x - 2, spec_y - 1);
        u8g2_DrawPixel(u8g2, peak_x, spec_y - 1);
        u8g2_DrawPixel(u8g2, peak_x + 2, spec_y - 1);
    }
    
    // 绘制频率刻度标记
    u8g2_SetFont(u8g2, u8g2_font_4x6_tf);
    char freq_str[16];
    
    // 峰值频率标记
    if (peak_frequency >= 1000) {
        snprintf(freq_str, sizeof(freq_str), "%.1fk", peak_frequency / 1000.0f);
    } else {
        snprintf(freq_str, sizeof(freq_str), "%.0f", peak_frequency);
    }
    // 调整标签位置避免超出边界
    uint8_t label_x = peak_x;
    if (label_x > spec_x + spec_width - 20) {
        label_x = spec_x + spec_width - 20;
    }
    if (label_x < spec_x) {
        label_x = spec_x;
    }
    u8g2_DrawStr(u8g2, label_x, spec_y + spec_height + 8, freq_str);
    
    // 最大频率标记
    if (max_display_freq >= 1000) {
        snprintf(freq_str, sizeof(freq_str), "%.0fk", max_display_freq / 1000.0f);
    } else {
        snprintf(freq_str, sizeof(freq_str), "%.0f", max_display_freq);
    }
    u8g2_DrawStr(u8g2, spec_x + spec_width - 16, spec_y + spec_height + 8, freq_str);
    
    // 显示FFT参数信息
    //u8g2_SetFont(u8g2, u8g2_font_5x7_tf);
   // u8g2_DrawStr(u8g2, 80, 10, "FFT");
    
    // 显示频率分辨率
    //snprintf(freq_str, sizeof(freq_str), "%.1fHz", freq_resolution);
    //u8g2_DrawStr(u8g2, 0, 63, freq_str);
    
    // 显示峰值频率和相对幅度
    snprintf(freq_str, sizeof(freq_str), "%.3fHz", peak_frequency);
    u8g2_DrawStr(u8g2, 80, 10, freq_str);
    
    snprintf(freq_str, sizeof(freq_str), "%.3fHz", peak_frequency);
    u8g2_DrawStr(u8g2, 80, 10, freq_str);

    snprintf(freq_str, sizeof(freq_str), "%.3fdB", 20.0f * log10f(peak));
    u8g2_DrawStr(u8g2,0, 10,freq_str);
    // 显示峰值的相对幅度（百分比）
    
    // 发送到显示器
    u8g2_SendBuffer(u8g2);
}